package com.gin.kotlin.gf2gamecommunity.composable.index

import androidx.annotation.DrawableRes
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.grid.itemsIndexed
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.Person
import androidx.compose.material3.AssistChip
import androidx.compose.material3.AssistChipDefaults
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import coil3.compose.AsyncImage
import coil3.compose.SubcomposeAsyncImage
import com.gin.kotlin.enums.QueryType
import com.gin.kotlin.gf2gamecommunity.R
import com.gin.kotlin.gf2gamecommunity.app.App
import com.gin.kotlin.gf2gamecommunity.base.composable.BorderCard
import com.gin.kotlin.gf2gamecommunity.base.composable.ExpandableCards
import com.gin.kotlin.gf2gamecommunity.base.composable.HorizontalCarousel
import com.gin.kotlin.gf2gamecommunity.base.composable.Loading
import com.gin.kotlin.gf2gamecommunity.base.composable.MyImage
import com.gin.kotlin.gf2gamecommunity.base.composable.TabInfo
import com.gin.kotlin.gf2gamecommunity.base.composable.TabRowPager
import com.gin.kotlin.gf2gamecommunity.navi.GF2Navigator
import com.gin.kotlin.gf2gamecommunity.routes.StrategyListRoute
import com.gin.kotlin.gf2gamecommunity.routes.ThemeDetailRoute
import com.gin.kotlin.gf2gamecommunity.routes.ThemeListRoute
import com.gin.kotlin.gf2gamecommunity.routes.TopicListRoute
import com.gin.kotlin.gf2gamecommunity.viewmodel.CommunityIndexViewModel
import com.gin.kotlin.gf2gamecommunity.viewmodel.UserFollowViewModel

data class IndexTab(
    val text: String,
    @DrawableRes val icon: Int,
    val content: @Composable () -> Unit,
)

/**
 * 社区首页
 * @param viewModel [CommunityIndexViewModel]
 * @param onNavigateToTopicList 导航到主题列表
 */
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun IndexCommunity(
    viewModel: CommunityIndexViewModel = viewModel(),
    navigator: GF2Navigator,
) {
    navigator.apply {
        Column {
            Banner(viewModel, onNavigateByUrl = { onNavigateByUrl(it) })
            TabRowPager(listOf(
                TabInfo("版面", R.drawable.ic_dashboard_24) {
                    CategoryGrid(viewModel, onNavigateToTopicList = { onNavigateToTopicList(it) })
                },
                TabInfo("话题", R.drawable.ic_grid_3x3_24) {
                    HotTheme(viewModel, onNavigateToThemeList = { onNavigateToThemeList(it) }, onNavigateToThemeDetail = { onNavigateToThemeDetail(it) })
                },
                TabInfo("推荐", iconVector = Icons.Filled.Person) {
                    UserRecommendTab()
                },
                TabInfo("攻略", R.drawable.ic_recommend_24) {
                    StrategyGroup(viewModel, onNavigateToStrategyList = { onNavigateToStrategyList(it) })
                },
            ), beyondViewportPageCount = 1)
        }
    }
}

@Composable
private fun Banner(viewModel: CommunityIndexViewModel = viewModel(), onNavigateByUrl: (url: String) -> Unit) {
    val bannerState = viewModel.banners.liveData.observeAsState()
    viewModel.banners.fetch()
    bannerState.value?.also { data ->
        HorizontalCarousel(data) {
            SubcomposeAsyncImage(model = it.imgAddr,
                contentDescription = null,
                loading = {
                    Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
                        CircularProgressIndicator(modifier = Modifier.size(64.dp))
                    }
                },
                modifier = Modifier
                    .fillMaxWidth()
                    .clickable { onNavigateByUrl(it.jumpAddr) })
        }
    } ?: Loading()
}


@Composable
private fun CategoryGrid(viewModel: CommunityIndexViewModel = viewModel(), onNavigateToTopicList: (route: TopicListRoute) -> Unit) {
    val categoryState = viewModel.categories.liveData.observeAsState()
    viewModel.categories.fetch(expire = 1800L)

    categoryState.value?.also { categories ->
        LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 128.dp), modifier = Modifier.padding(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp),
            verticalArrangement = Arrangement.spacedBy(8.dp)) {
            itemsIndexed(categories) { _, item ->
                BorderCard {
                    Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier
                        .fillMaxWidth()
                        .padding(4.dp)
                        .clickable {
                            // 根据id是否为“关注”分类决定查询类型
                            val queryType = if (item.id == 100) QueryType.FOLLOW else QueryType.NORMAL
                            onNavigateToTopicList(TopicListRoute(queryType = queryType, categoryId = item.id))
                        }) {
                        AsyncImage(model = item.imgC, contentDescription = null, modifier = Modifier.size(50.dp))
                        Text(item.name, fontSize = 22.sp, modifier = Modifier.graphicsLayer { alpha = 0.7f })
                    }
                }
            }
        }
    } ?: Loading()


}


@Composable
private fun StrategyGroup(viewModel: CommunityIndexViewModel = viewModel(), onNavigateToStrategyList: (route: StrategyListRoute) -> Unit) {
    val cachedLiveData = viewModel.strategyGroups
    val state = cachedLiveData.liveData.observeAsState()
    cachedLiveData.fetch(expire = 1800L)

    state.value?.also { list ->
        ExpandableCards(
            items = list,
            itemTitle = { it.name },
            itemContent = { group ->
                Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
                    group.subStrategy.forEach { item ->
                        Text(item.name, fontSize = 22.sp, modifier = Modifier
                            .fillMaxWidth()
                            .graphicsLayer { alpha = 0.7f }
                            .clickable {
                                onNavigateToStrategyList(StrategyListRoute(title = "${group.name} - ${item.name}", subStrategyId = item.id))
                            })
                    }
                }
            },
        )
    } ?: Loading()
}

@Composable
private fun HotTheme(
    viewModel: CommunityIndexViewModel = viewModel(),
    onNavigateToThemeList: (route: ThemeListRoute) -> Unit,
    onNavigateToThemeDetail: (route: ThemeDetailRoute) -> Unit,
) {
    val cachedLiveData = viewModel.hotThemes
    val state = cachedLiveData.liveData.observeAsState()
    cachedLiveData.fetch(expire = 1800L)
    val list = state.value
    if (list.isNullOrEmpty()) {
        Loading()
        return
    }
    Column(modifier = Modifier.padding(8.dp)) {
        Button(onClick = { onNavigateToThemeList(ThemeListRoute()) }) { Text("话题中心") }
        LazyColumn(verticalArrangement = Arrangement.spacedBy(8.dp)) {
            items(items = list) { item ->
                Text("#${item.name}", fontSize = 22.sp, modifier = Modifier
                    .fillMaxWidth()
                    .graphicsLayer { alpha = 0.7f }
                    .clickable { onNavigateToThemeDetail(ThemeDetailRoute(item.id)) })
            }
        }
    }
}

/**
 * 关注推荐标签
 * @param modifier Modifier
 */
@Composable
private fun UserRecommendTab(viewModel: UserFollowViewModel = viewModel(), modifier: Modifier = Modifier) {
    viewModel.userRecommend.fetch(expire = 60)
    val state = viewModel.userRecommend.liveData.observeAsState()
    state.value?.also { list ->
        Column(Modifier.padding(8.dp)) {
            Button(onClick = { viewModel.userRecommend.fetch(true) }) { Text("换一批") }
            LazyVerticalGrid(columns = GridCells.Fixed(3)) {
                items(items = list, key = { it.uid }) { item ->
                    item.apply {
                        var followed by remember(uid) { mutableStateOf(isFollow) }
                        Column(verticalArrangement = Arrangement.spacedBy(4.dp), horizontalAlignment = Alignment.CenterHorizontally) {
                            MyImage(model = avatar, modifier = Modifier
                                .clip(CircleShape)
                                .width(80.dp))
                            Text(nickName, fontWeight = FontWeight.Bold, maxLines = 1)
                            // todo 替换为 FollowChip
                            AssistChip(onClick = {
                                viewModel.follow(uid) {
                                    App.toast(it)
                                    followed = !followed
                                    isFollow = followed
                                }
                            }, label = { Text(if (followed) "已关注" else "未关注") }, leadingIcon = {
                                Icon(if (followed) Icons.Filled.Check else Icons.Filled.Add, contentDescription = null, Modifier.size(AssistChipDefaults.IconSize))
                            })
                        }
                    }
                }
            }
        }
    } ?: Loading()
}